#include "GlutFunc.h"
#include "CorbaSender.h"
// OpenNI lib
#include <XnOpenNI.h>
#include <XnCodecIDs.h>
#include <XnCppWrapper.h>
// OpenGL & GLUT
#if (XN_PLATFORM == XN_PLATFORM_MACOSX)
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include "SceneDrawer.h"

#define GL_WIN_SIZE_X 720
#define GL_WIN_SIZE_Y 480

extern CorbaSender* sender;

extern xn::Context g_Context;
extern xn::DepthGenerator g_DepthGenerator;
extern xn::UserGenerator g_UserGenerator;

extern XnBool g_bNeedPose;
extern XnChar g_strPose[20];
extern XnBool g_bDrawBackground;
extern XnBool g_bDrawPixels;
extern XnBool g_bDrawSkeleton;
extern XnBool g_bPrintID;
extern XnBool g_bPrintState;
extern XnBool g_bPause;
extern XnBool g_bRecord;
extern XnBool g_bQuit;


void glutDisplay(void) {

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Setup the OpenGL viewpoint
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();

  xn::SceneMetaData sceneMD;
  xn::DepthMetaData depthMD;
  g_DepthGenerator.GetMetaData(depthMD);
  glOrtho(0, depthMD.XRes(), depthMD.YRes(), 0, -1.0, 1.0);

  glDisable(GL_TEXTURE_2D);

  if (!g_bPause) {
    // Read next available data
    g_Context.WaitAndUpdateAll();
  }

  // Process the data
  g_DepthGenerator.GetMetaData(depthMD);
  g_UserGenerator.GetUserPixels(0, sceneMD);
  DrawDepthMap(depthMD, sceneMD);
  sender->send(g_UserGenerator);

  glutSwapBuffers();
}

void glutIdle(void) {
  if (g_bQuit) {
    CleanupExit();
  }
  glutPostRedisplay();
}

void glutKeyboard(unsigned char key, int x, int y) {
  switch (key) {
  case 27:
    CleanupExit();
  case 'b':
    // Draw background?
    g_bDrawBackground = !g_bDrawBackground;
    break;
  case 'x':
    // Draw pixels at all?
    g_bDrawPixels = !g_bDrawPixels;
    break;
  case 's':
    // Draw Skeleton?
    g_bDrawSkeleton = !g_bDrawSkeleton;
    break;
  case 'i':
    // Print label?
    g_bPrintID = !g_bPrintID;
    break;
  case 'l':
    // Print ID & state as label, or only ID?
    g_bPrintState = !g_bPrintState;
    break;
  case 'p':
    g_bPause = !g_bPause;
    break;
  }
}
void glInit(int * pargc, char ** argv) {
  glutInit(pargc, argv);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  glutInitWindowSize(GL_WIN_SIZE_X, GL_WIN_SIZE_Y);
  glutCreateWindow("KiBeam Client");
  //glutFullScreen();
  glutSetCursor(GLUT_CURSOR_NONE);

  glutKeyboardFunc(glutKeyboard);
  glutDisplayFunc(glutDisplay);
  glutIdleFunc(glutIdle);

  glDisable(GL_DEPTH_TEST);
  glEnable(GL_TEXTURE_2D);

  glEnableClientState(GL_VERTEX_ARRAY);
  glDisableClientState(GL_COLOR_ARRAY);
}


void CleanupExit() {
  g_Context.Shutdown();

  exit(1);
}
